#include <QtSql/QSqlDriver>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QMessageBox>
#include <QVariant>
#include "conexion.h"
#include <stdlib.h>
#include <ctime>

conexionDB* conexionDB::_instance = 0;
Datos* conexionDB::dtsAll = 0;
datosCnt* conexionDB::dtsCnt = 0;

conexionDB* conexionDB::instance( ){
    if( _instance == 0 ){
        _instance = new conexionDB;
    }
    return _instance;
}


Datos* conexionDB::instanceDats( ){
    if( dtsAll == 0 ){
        dtsAll = new Datos;
    }
    return dtsAll;
}
datosCnt* conexionDB::instanceCnts( ){
    if( dtsCnt == 0 ){
        dtsCnt = new datosCnt;
        dtsCnt->number = 1;
        //dtsCnt = (struct datosCnt*) malloc( sizeof(datosCnt)+1 );
    }
    return dtsCnt;
}

//FUNCION PARA LIMPIAR LOS DATOS DE LA ESTRUCTURA
void conexionDB::clearDtsAll( void ){
    dtsAll->nombre.clear();
    dtsAll->apellidos.clear();
    dtsAll->sexo.clear();
    dtsAll->edad.clear();
    dtsAll->email.clear();
    dtsAll->celular.clear();
    dtsAll->telefono.clear();
    dtsAll->telefonot.clear();
    dtsAll->extencion.clear();
    dtsAll->fax.clear();
    dtsAll->fechareg.clear();
    dtsAll->nota.clear();
    dtsAll->emailt.clear();
    dtsAll->twitter.clear();
    dtsAll->web.clear();
    dtsAll->facebook.clear();
    dtsAll->id.clear();
    return;
}
//FUNCION QUE SIRVE PARA INSERTAR LOS DATOS EN LA BASE DE DATOS
//SEGUN LA TABLA INDICADA
//FUNCION NO COMPLETA HAY QUE ORDENAR LOS DATOS!!!
void conexionDB::initDatsDataBase( const QString &table ){
    time_t tiempo = time(0);
    struct tm *tlocal = localtime(&tiempo);
    char output[128];
    strftime(output,128,"%d/%m/%y %H:%M:%S",tlocal);
    QSqlQuery *add = new QSqlQuery( db );
    /*add->prepare( "INSERT INTO '"+table+"'(Nombre, Apellidos, Edad, Sexo, Telefono, Celular, Email, Nota, FechaInsercion, Imagen, Email2, Web, Twitter, Facebook, ID ) \
                  VALUES('"+dtsAll->nombre+"', '"+dtsAll->apellidos+"', '"+dtsAll->edad+"',\
                         '"+dtsAll->sexo+"', '"+dtsAll->telefono+"'  ,'"+dtsAll->celular+"' ,\
                         '"+dtsAll->email+"', '"+dtsAll->nota+"', '"+output+"', '"+dtsAll->email+"', \
                         '"+dtsAll->emailt+"', '"+dtsAll->web+"', '"+dtsAll->twitter+"', '"+dtsAll->facebook+"', \
                         '"+dtsAll->id+"' ) " );*/
    add->prepare( "INSERT INTO '"+table+"'(Nombre, Apellidos, Edad, Sexo, Telefono, Celular, Email, Direccion, Telefono2, Extencion, Fax, Nota, FechaInsercion, Imagen, Email2, Web, Twitter, Facebook, ID ) \
                    VALUES('"+dtsAll->nombre+"', '"+dtsAll->apellidos+"', '"+dtsAll->edad+"',\
                        '"+dtsAll->sexo+"', '"+dtsAll->telefono+"'  ,'"+dtsAll->celular+"' ,\
                        '"+dtsAll->email+"',\
                        '"+dtsAll->direccion+"', '"+dtsAll->telefonot+"', '"+dtsAll->extencion+"', '"+dtsAll->fax+"' , \
                        '"+dtsAll->nota+"', '"+output+"', '"+dtsAll->email+"', \
                        '"+dtsAll->emailt+"', '"+dtsAll->web+"', '"+dtsAll->twitter+"', '"+dtsAll->facebook+"', \
                        '"+dtsAll->id+"' ) " );
    if( add->exec() == true ){
    }else{
        QMessageBox::warning( 0, "ERROR", "Error al insertar los datos", QMessageBox::Ok );
        //QMessageBox::warning( 0, "Error", add->lastError() , QMessageBox::Ok );
    }
    if( add!= NULL ){
        delete add;
    }
    return;
}

conexionDB::conexionDB( ){
    /*if( db.open() ){
        db.close();
    }*/
    //QSqlDatabase::removeDatabase( "Demo" );
    //db = QSqlDatabase::addDatabase("QSQLITE", "Demo");
    //BASE DE LA LISTA ENLAZADA A NOMBRES DE BUSQUEDA
    //dtsCnt = NULL;
}
conexionDB::~conexionDB( ){
    if( db.open() ){
        db.close();
    }
    if( dtsAll != NULL ){
        delete dtsAll;
    }
    if( dtsCnt != NULL ){
        free(dtsCnt);
    }
}

//FUNCION QUE INDICA LA BASE DE DATOS A USAR
//RETORNA TRUE SI NO HUBO PROBLEMAS CON LA BASE DE DATOS
//FALSE EN CASO CONTRARIO
bool conexionDB::addDatabaseDb3( const char *DB ){
    //db = QSqlDatabase::addDatabase("QSQLITE");
    db = QSqlDatabase::addDatabase("QSQLITE" );
    db.setDatabaseName( DB );
    if( db.databaseName() == DB ){
        return true;
    }else{
        return false;
    }
    return false;
}

//FUNCION PARA REALIZAR LA CONEXION CON LA BASE DE DATOS
bool conexionDB::createConexionDb3( void ){
    if( !db.open() ){
        QMessageBox::critical( 0, "ERROR", "ERROR  AL CONECTAR CON LA BASE DE DATOS", QMessageBox::Ok );
        return false;
    }else{
        QMessageBox::warning( 0, "EXITO", "EXITO  AL CONECTAR CON LA BASE DE DATOS", QMessageBox::Ok );
    }
    return true;
}

//FUNCION QUE INDICA SI HAY DATOS DE ALGUN USUARIO
//DENTRO DE LA BASE DE DATOS
bool conexionDB::userInUse( void ){
    QSqlQuery *showD = new QSqlQuery( db );
    showD->prepare( "SELECT * FROM usuario" );
    showD->exec();
    QVariant extra;
    if( showD->first() ){
        extra = showD->value("Enuso");
    }
    if( showD != NULL ){
        delete showD;
    }
    //QMessageBox::warning(0, "ABC", extra.toString(), QMessageBox::Ok );
    if( extra.toString() == "false" ){
        return false;
    }else{
        return true;
    }
    return false;
}
//FUNCION QUE INSERTA EN LA TABLA 'usuario' LO QUE
//SE LE PASA COMO REFERENCIA  A LA FUNCION
void conexionDB::userUse( const QString use ){
    QSqlQuery *add = new QSqlQuery( db );
    //add->prepare( "INSERT INTO usuario( Enuso ) VALUES('"+ name +"')" );
    add->prepare( "UPDATE usuario SET Enuso='"+ use +"' WHERE rowid=1" );
    add->exec( );
    if( add!= NULL ){
        delete add;
    }
    return;
}

//FUNCION QUE INDICA SI LA CONEXION CON LA BASE DE DATOS
//SE ENCUENTRA ACTIVA TRUE SI ESTA ACTIVA FALSE EN
//CASO CONTRARIO
bool conexionDB::inUseConexionDb3( void ){
    if( !db.open() ){
        return false;
    }
    return true;
}

//FUNCION PARA TERMINAR LA CONEXION CON LA BASE DE DATOS
void conexionDB::closeConexionDb3( void ){
    QMessageBox::warning( 0, "Cerrar conexion", "EXITO  AL DESCONECTAR CON LA BASE DE DATOS", QMessageBox::Ok );
    db.close();
    //QSqlDatabase::removeDatabase( "Demo" );
    return;
}
//FUNCION QUE RETORNA TRUE SI LA CONEXION ESTA ACTIVA
//FALSE EN CASO CONTRARIO
bool conexionDB::stateConexionDb3( void ){
    if( !db.open() ){
        QMessageBox::critical( 0, "AVISO", "HAY CONEXION CON LA BASE DE DATOS", QMessageBox::Ok );
        return false;
    }else{
        QMessageBox::warning( 0, "AVISO", "NO HAY CONEXION CON LA BASE DE DATOS", QMessageBox::Ok );
    }
    return true;
}


//PARA MANEJAR LOS DATOS DEL USUARIO
//FUNCION QUE AGREGA LOS DATOS DEL USUARIO
bool conexionDB::addDatsUser( const QString &name ){
    QMessageBox::warning( 0, "entra", "enstra", QMessageBox::Ok );
    QSqlQuery *add = new QSqlQuery( db );
    add->prepare( "INSERT INTO misdatos( Nombre ) VALUES('"+ name +"') " );
    add->exec( );
    if( add!= NULL ){
        delete add;
    }
    //add.exec( "select Nombre from misdatos" );
    return true;
}
bool conexionDB::addDatsUser(const QString &name, const QString &appep, const QString &edad, \
        const QString &sexo, const QString &telefono, \
        const QString &celular, const QString &email , const QString &nota){
    time_t tiempo = time(0);
    //struct tm *tlocal = localtime_s( &tiempo, &tiempo );
    struct tm *tlocal = localtime(&tiempo);
    char output[128];
    strftime(output,128,"%d/%m/%y %H:%M:%S",tlocal);
    QSqlQuery *add = new QSqlQuery( db );
    add->prepare( "INSERT INTO misdatos( Nombre, Apellidos, Edad, Sexo, Telefono, Celular, Email, Nota, FechaRegistro ) \
                  VALUES('"+ name +"', '"+ appep +"', '"+ edad +"', '"+ sexo +"', \
                         '"+ telefono +"'  ,'"+ celular +"' ,'"+ email +"', '"+nota+"', '"+ output +"' ) " );
    //add->exec( );
    if( add->exec() == true ){
    }else{
    }
    if( add!= NULL ){
        delete add;
    }
    return true;
}

//FUNCION QUE RETORNA UN PUNTERO A LA ESTRUCTURA mDatos
//QUE ES LA ENCARGADA DE REGRESAR LOS DATOS PERSONALES
//QUE SE MOSTRARAN
mDatos* conexionDB::showDatsUser( void ){
    QSqlQuery *showD = new QSqlQuery( db );
    mDatos *dats = new mDatos;
    showD->prepare( "SELECT * FROM misdatos" );
    showD->exec();
    QVariant extra;
    if( showD->first() ){
        extra = showD->value("Nombre");
        dats->name = extra.toString();
        extra = showD->value("Apellidos");
        dats->apellidos = extra.toString();
        extra = showD->value("Sexo");
        dats->sexo = extra.toString();
        extra = showD->value("Edad");
        dats->edad = extra.toString();
        extra = showD->value("Email");
        dats->email = extra.toString();
        extra = showD->value("Celular");
        dats->celular = extra.toString();
        extra = showD->value("Telefono");
        dats->telefono = extra.toString();
        extra = showD->value("FechaRegistro");
        dats->fechareg = extra.toString();
        extra = showD->value("Nota");
        dats->nota = extra.toString();
    }
    if( showD != NULL ){
        delete showD;
    }
    return dats;
}

//FUNCION QUE GUARDA EN LA LISTA ENLAZADA SIMPLE NOMBRE
//Y APELLIDOS DE LOS CLIENTES
//FUNCION QUE RECIBE COMO NOMBRE LA TABLA A BUSCAR
void conexionDB::bDbCntl(const QString table ){
    QSqlQuery *brw = new QSqlQuery( db );
    brw->prepare( "SELECT Nombre, Apellidos FROM '"+table+"'" );
    brw->exec();
    int aux = 1;
    while( brw->next() ){
        addDbCntl( &(dtsCnt), brw->value("Nombre").toString(), \
                 brw->value("Apellidos").toString(), aux);
        aux += 1;
    }

    return;
}
//FUNCION QUE METE LOS DATOS A LA LISTA ENLAZADA
void conexionDB::addDbCntl(struct datosCnt **lista, const QString Nombre, const QString Apellidos, short int number){
    if( number == 1 ){
        (*lista)->name.append( Nombre );
        (*lista)->apellidos.append( Apellidos );
        (*lista)->next = NULL;
        return;
    }else{
        if( (*lista) == NULL ){
            (*lista) = new datosCnt;
            (*lista)->name.append( Nombre );
            (*lista)->apellidos.append( Apellidos );
            (*lista)->number = number;
            (*lista)->next = NULL;
            return;
        }else{
            addDbCntl( &((*lista)->next), Nombre, Apellidos, number );
        }
    }
    return ;
}
//FUNCION QUE LIMPIA LA LISTA ENLAZADA Y LA DEJA LISTA PARA
//SER USADA NUEVAMENTE
void conexionDB::clearCntl( void ){
    clearAllCntl( &(dtsCnt) );
    dtsCnt = 0;
    return;
}
void conexionDB::clearAllCntl( struct datosCnt** lista ){
    if( (*lista) != NULL ){
        if( ((*lista)->next) != NULL ){
            clearAllCntl( &((*lista)->next) );
        }
        (*lista)->name.clear();
        (*lista)->apellidos.clear();
        (*lista)->number = 0;
        delete (*lista);
    }
    return;
}


//ESTA FUNCION USA LA MISMA ESTRUSTURA DE DATOS
void conexionDB::showDatsCntl(const QString name, const QString Apellidos , const QString table){
    QSqlQuery *showD = new QSqlQuery( db );
    showD->prepare( "SELECT * FROM '"+table+"' \
                    WHERE Nombre='"+name+"' AND Apellidos='"+Apellidos+"' " );
    showD->exec();
    if( showD->first() ){
        QVariant extra;
        extra = showD->value("Nombre");
        dtsAll->nombre = extra.toString();
        extra = showD->value("Apellidos");
        dtsAll->apellidos = extra.toString();
        extra = showD->value("Edad");
        dtsAll->edad = extra.toString();
        extra = showD->value("Sexo");
        dtsAll->sexo = extra.toString();
        extra = showD->value("Email");
        dtsAll->email = extra.toString();
        extra = showD->value("Email2");
        dtsAll->emailt = extra.toString();
        extra = showD->value("Celular");
        dtsAll->celular = extra.toString();
        extra = showD->value("Telefono");
        dtsAll->telefono = extra.toString();
        extra = showD->value("Web");
        dtsAll->web = extra.toString();
        extra = showD->value("Twitter");
        dtsAll->twitter = extra.toString();
        extra = showD->value("Facebook");
        dtsAll->facebook = extra.toString();
        extra = showD->value("ID");
        dtsAll->id = extra.toString();
        extra = showD->value( "Nota" );
        dtsAll->nota = extra.toString();
        extra = showD->value( "FechaInsercion" );
        dtsAll->fechareg = extra.toString();

        extra = showD->value( "Direccion" );
        dtsAll->direccion = extra.toString();
        extra = showD->value( "Telefono2" );
        dtsAll->telefonot = extra.toString();
        extra = showD->value( "Extencion" );
        dtsAll->extencion = extra.toString();
        extra = showD->value( "Fax" );
        dtsAll->fax = extra.toString();
    }
    return;
}

//FUNCION QUE BORRA LOS DATOS DE LA TABLA CLIENTES
void conexionDB::clearDatsCntl( const QString name, const QString Apellidos, const QString table ){
    QSqlQuery *showD = new QSqlQuery( db );
    showD->prepare( "DELETE FROM '"+table+"' \
                        WHERE Nombre='"+name+"' AND Apellidos='"+Apellidos+"'" );
    showD->exec();
    if( showD != NULL ){
        delete showD;
    }
    return;
}

//FUNCION PARA LIBERAR A MEMORIA
void conexionDB::clearAll( void ){
    conexionDB::~conexionDB();
}


